home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / DNet / DSMTPclient.cpp < prev    next >
Encoding:
Text File  |  1996-07-05  |  6.0 KB  |  268 lines  |  [TEXT/R*ch]

  1. // DSMTP.cp 
  2. // SMTP Mail sender
  3. // by D. Gilbert, May 1991
  4.  
  5.  
  6. #include <ncbi.h>
  7. #include <dgg.h>
  8. #include "DSMTPclient.h"
  9.  
  10.  
  11. const short    kSMTPport = 25;
  12. static const    long    kMaxInt     = 32000;    
  13.  
  14.  
  15.  
  16.  
  17. // DSMTP .............................
  18.  
  19. DSMTP::DSMTP()
  20. {
  21.     InitData();
  22. }
  23.  
  24. DSMTP::DSMTP( char* SMTPHostName)
  25. {
  26.     InitData();
  27.     ResetHost( SMTPHostName);
  28. }
  29.  
  30. DSMTP::~DSMTP()
  31. {
  32.     if (fSMTPhostname) MemFree(fSMTPhostname);
  33.     if (fMailerID) MemFree(fMailerID);
  34. }
  35.  
  36. void DSMTP::ResetHost( char* SMTPHostName)
  37. {
  38.     if (fSMTPhostname) fSMTPhostname= (char*)MemFree( fSMTPhostname);
  39.     if (!NameToAddress(SMTPHostName)) {
  40.         Nlm_Message (MSG_ERROR, "DSMTP::ResetHost: Bad SMTP host address");
  41.         return; 
  42.         }
  43.     fSMTPhostname= StrSave( SMTPHostName);
  44. }
  45.  
  46. void DSMTP::InitData()
  47. {
  48.   char  buf[256];
  49.   fSMTPhostname= NULL;
  50.     fCheckReturnAddress= false; // forget this for now, fails too often on good addresses
  51.     sprintf( buf, "DClap-SMTP %s", (char*)VersionString());
  52.     fMailerID= StrSave(buf);
  53. }
  54.  
  55. void DSMTP::CheckReturnAddress( Boolean docheck)
  56. {
  57.     fCheckReturnAddress= docheck;
  58. }
  59.  
  60.  
  61.  
  62. void DSMTP::SendMail( char* theTo,  char*  theFrom,  char*  theSubject, 
  63.                                      char* theCCopy,  char*  theMessage)
  64. {
  65.     const short maxEndLine = 81;
  66.     const short minEndLine = 40;
  67.     long  i, nLines;
  68.     short linewidth, maxLines= 100;
  69.     long  hlen= strlen(theMessage);
  70.     
  71.     //if (hlen > kMaxInt) hlen= kMaxInt; // error !?!
  72.     long* hLines= (long*) MemNew( (maxLines+1) * sizeof(long));
  73.     hLines[0]= 0;
  74.     
  75.     char* buf = (char*) theMessage;
  76.     for (i= 1, linewidth= 0, nLines= 0; i <= hlen; buf++, linewidth++, i++ ) {
  77.             
  78.         if (*buf == kCR || *buf == kLF || linewidth > maxEndLine || i == hlen) {
  79.             nLines++;
  80.             if (nLines > maxLines) {
  81.                 maxLines= nLines + 100;
  82.                 hLines= (long*) Nlm_MemMore( hLines, (maxLines+1) * sizeof(long));
  83.                 }
  84.             if (*buf == kCR || *buf == kLF || i == hlen) 
  85.                 hLines[nLines]= i;  
  86.             else {
  87.                 while ( (*buf > ' ')  &&  (linewidth > minEndLine)) {
  88.                     buf--;
  89.                     linewidth--;
  90.                     i--;
  91.                     }
  92.                 if (*buf > ' ') {
  93.                     short k= maxEndLine - linewidth;
  94.                     buf += k;
  95.                     linewidth += k;
  96.                     i += k;
  97.                     }                    
  98.                 hLines[nLines]= i;
  99.                 }
  100.             linewidth= 0;
  101.             }
  102.         }
  103.         
  104.     SendMail( theTo, theFrom, theSubject, theCCopy, theMessage, hLines, nLines);
  105.     MemFree(hLines);
  106. }
  107.  
  108.  
  109.  
  110.  
  111.  
  112. Boolean DSMTP::WaitHandshake( char OkayCode)
  113. {
  114.     char* aChars= RecvLine(); 
  115.     if (!aChars) {
  116.         return false;
  117.         }
  118.     else if (*aChars != OkayCode) {
  119.         Fail( aChars); 
  120.         MemFree( aChars);
  121.         return false;
  122.         }
  123.     else {
  124.         MemFree( aChars);
  125.         return true;
  126.         }
  127. }
  128.  
  129.  
  130. void DSMTP::SendMail( char * theTo,  char * theFrom,  char * theSubject, 
  131.                  char * theCCopy,  char * theMessage, long pLines[], long nLines)
  132. {
  133.     const    short    kBufmax= 512;
  134.   char    buf[kBufmax+1];
  135.   char aName[255], aDate[255];
  136.     long    i, k, bytesread;
  137.     long* pLineStart;
  138.     Boolean mailSent= false;    
  139.     Boolean okay= true;
  140.     char *namep, *line;
  141.     
  142.   if (fSMTPhostname == NULL) {
  143.         Nlm_Message (MSG_ERROR, "DSMTP::SendMail: Bad SMTP host address");
  144.         return;
  145.         }
  146.   if (theFrom == NULL || *theFrom == 0) {
  147.         okay= false;
  148.       }
  149.     if (okay && fCheckReturnAddress) {
  150.         char* kp= strchr(theFrom,'@');
  151.         okay= (kp != NULL);
  152.         if (okay) okay= (NameToAddress(kp+1) != 0);
  153.         }
  154.     if (!okay) {
  155.         Nlm_Message (MSG_ERROR, "DSMTP::SendMail: Bad return address");
  156.         return;
  157.         }
  158.   if (theMessage == NULL || *theMessage == 0) {
  159.         Nlm_Message (MSG_ERROR, "DSMTP::SendMail: Missing DATA.");
  160.     return;
  161.       }
  162.   if (theTo == NULL || *theTo == 0) {
  163.         Nlm_Message (MSG_ERROR, "DSMTP::SendMail: Missing TO address");
  164.     return;
  165.       }
  166.     
  167.     Open(fSMTPhostname, kSMTPport);
  168.     if ( Failed()) return;  
  169.     if (!WaitedForOpen()) return;
  170.     EatResponseLine();  // SMTP SendMail title from host ??
  171.     
  172.     sprintf( buf, "HELO %s"CRLF,theFrom);
  173.     SendStr( buf, kDontAddCRLF);
  174.     EatResponseLine();
  175.  
  176.     sprintf(buf, "MAIL FROM: <%s>"CRLF, theFrom);
  177.     SendStr(buf, kDontAddCRLF);
  178.     if (!WaitHandshake('2')) goto quitSMTP;    
  179.   
  180.     strcpy(aName,theTo); 
  181.     namep= aName;
  182.     for ( k= 1; k<= 2; k++) {
  183.         while (namep && *namep) {
  184.             line= RecvChars( CharsAvailable(), bytesread);
  185.             MemFree( line);
  186.             
  187.             char* nameend= strchr(namep, ',');
  188.             if (nameend) *nameend= 0;            
  189.             sprintf(buf, "RCPT TO: <%s>"CRLF, namep);
  190.             SendStr(buf, kDontAddCRLF);
  191.             if (!WaitHandshake('2')) goto quitSMTP;    
  192.             if (nameend) namep= nameend+1;
  193.             else namep= NULL;
  194.             }
  195.         if (theCCopy) { strcpy( aName, theCCopy); namep= aName; }
  196.         else namep= NULL;
  197.         }
  198.         
  199.     line= RecvChars( CharsAvailable(), bytesread);
  200.     MemFree( line);
  201.     SendStr("DATA"CRLF, kDontAddCRLF);
  202.     if (!WaitHandshake('3')) goto quitSMTP;    
  203.     
  204.     // send header lines... 
  205.     sprintf(buf, "From: %s"CRLF, theFrom);
  206.   SendStr(buf, kDontAddCRLF);
  207.     sprintf(buf, "To: %s"CRLF, theTo);
  208.     SendStr(buf, kDontAddCRLF);
  209.     if (theCCopy && *theCCopy) {
  210.         sprintf(buf, "Cc: %s"CRLF, theCCopy);
  211.         SendStr(buf, kDontAddCRLF);
  212.         }
  213.     sprintf(buf, "Subject: %s"CRLF, (theSubject)?theSubject:"");
  214.     SendStr(buf, kDontAddCRLF);
  215.     
  216.     if (Nlm_DayTimeStr( aDate, true, true)) {
  217.         sprintf(buf, "Date: %s"CRLF, aDate);
  218.         SendStr(buf, kDontAddCRLF);
  219.         }
  220.         
  221.     sprintf(buf, "X-Mailer: %s"CRLF, fMailerID);
  222.     SendStr(buf, kDontAddCRLF);
  223.     SendCRLF(); //blank line
  224.     
  225.     // send message buffer 
  226.     pLineStart= (long*) pLines;
  227.     for (i= 0; i< nLines; i++) {
  228.         char* bufPtr= theMessage + pLineStart[i];
  229.         long len=  pLineStart[i+1] - pLineStart[i];
  230.         if (i+1 == nLines  &&  pLineStart[i+1] != *LineEnd) len++; // ensure last char is sent.
  231.         //if ((len>0) && (bufPtr[len-1] == *LineEnd)) len--;
  232.         if ((len>0) && (bufPtr[len-1] == kCR || bufPtr[len-1] == kLF)) len--;
  233.         if (len<1)
  234.             SendCRLF();
  235.         else if (*bufPtr == '.') {
  236.             if (len > kBufmax-1) len= kBufmax-1;  
  237.             buf[0]= '.';
  238.             MemCopy( &buf[1], bufPtr, len);
  239.             SendBytes( buf, len);
  240.             SendCRLF();
  241.             }        
  242.         else {
  243.             SendBytes( bufPtr, len);
  244.             SendCRLF();
  245.             }
  246.         }
  247.  
  248.     SendStr("."CRLF, kDontAddCRLF);
  249.     //if (!WaitHandshake('2')) goto quitSMTP;    
  250.     // ^^ Not getting '2' here, but "R?? mail received..."
  251.     //line= RecvLine(); MemFree( line);
  252.      mailSent= true;
  253.  
  254. quitSMTP:
  255.     line= RecvChars( CharsAvailable(), bytesread);
  256.     MemFree( line);
  257.     SendStr("QUIT"CRLF, kDontAddCRLF);
  258.     
  259.     //fTimeout= 100; //?? want short timeout here waiting for recvline
  260.     //line= RecvLine(); MemFree( line);
  261.     Close();
  262.     Release();
  263.     return;
  264. }  
  265.  
  266.  
  267.  
  268.